#include <iostream>

#include <string>
#include <log4cxx/logger.h>
#include <log4cxx/xml/domconfigurator.h>

#include "NameSvrClient.h"

using std::cout;
using std::endl;

using namespace log4cxx;

#define THREAD_NUM 1

pthread_mutex_t g_mutex;

string g_log_conf_file;

int parse_args(int argc, char * argv[]) {
        char c;
        while(-1 != (c = getopt(argc, argv, "l:"))) {
                switch(c) {
                        case 'l':
                                g_log_conf_file = optarg;
                                break;

                        default:
                                break;
                }
        }
        return 1;
}

int add_counter() {
	static int counter = 0;
	static time_t start_t = time(NULL);
	pthread_mutex_lock(&g_mutex);
	counter++;
	pthread_mutex_unlock(&g_mutex);
	if (counter % 1000 == 0) {
		cout << "rate:" << counter / (time(NULL) - start_t + 1) << endl;
	}
	return 1;
}

void * test_thread_routine(void * arg) {
	NameSvrClient * nsc = (NameSvrClient *)arg;
	while (true) {
		FILE_METADATA_INFO info;
		char file_name[1024];
		char dir_name[1024];
		snprintf(dir_name, sizeof(dir_name), "/test_dir_%d", rand());
		snprintf(file_name, sizeof(file_name), "%s/test_file_%d", dir_name, rand());
		int exist_flag;
		int ret = nsc->query_is_dir_exist(dir_name, exist_flag);
		if (ret < 0) cout << "query_is_dir_exist fail, dir:" << dir_name << ", ret:" << ret << endl;
		ret = nsc->create_dir(dir_name);
		if (ret < 0) cout << "create dir fail, dir:" << dir_name << ", ret:" << ret << endl;
		ret = nsc->query_is_dir_exist(dir_name, exist_flag);
		if (ret < 0 || 1 != exist_flag) cout << "query_is_dir_exist fail, dir:" << dir_name << ", ret:" << ret << endl;
		ret = nsc->get_file_metadata_info(dir_name, info);
		if (ret < 0) cout << "get file metadata svr info, file:" << dir_name << ", ret:" << ret << endl;
		cout << "dir:" << dir_name << ", metadata info num_hard_link:" << info.num_hard_link << ", file_type:" << \
			info.file_type << endl;
		ret = nsc->query_is_file_exist(file_name, exist_flag);
		if (ret < 0) cout << "query_is_file_exist fail, file:" << file_name << ", ret:" << ret << endl;
		ret = nsc->create_file(file_name, 1, 2, 3);
		if (ret < 0) cout << "create file:" << file_name << ", ret:" << ret << endl;
		ret = nsc->query_is_file_exist(file_name, exist_flag);
		if (ret < 0 || 1 != exist_flag) cout << "query_is_file_exist fail, file:" << file_name << ", ret:" << ret << endl;
		ret = nsc->get_file_metadata_info(file_name, info);
		if (ret < 0) cout << "get file metadata svr info, file:" << file_name << ", ret:" << ret << endl;
		cout << "file:" << file_name << ", metadata info num_hard_link:" << info.num_hard_link << ", file_type:" << \
			info.file_type << ", mds_id:" << info.mds_id << ", dir_id:" << info.dir_id << ", file_id:" << \
			info.file_id << endl;
		ret = nsc->delete_file(file_name);	
		if (ret < 0) cout << "delete file:" << file_name << ", ret:" << ret << endl;
		ret = nsc->delete_dir(dir_name);
		if (ret < 0) cout << "delete dir fail, dir:" << dir_name << ", ret:" << ret << endl;
		int32_t mds_id;
		ret = nsc->alloc_mds_4_new_file(mds_id);
		if (ret < 0) cout << "alloc mds error, ret:" << ret << endl;
		list<string> entries;
		ret = nsc->read_dir("/", entries);
		if (ret < 0) cout << "read_dir error, ret:" << ret << endl;
		for(list<string>::const_iterator iter = entries.begin(); entries.end() != iter; iter++) {
			cout << "entry:" << *iter << endl;
		}
		add_counter();
		return NULL;
	}
}

int test() {
	log4cxx::xml::DOMConfigurator::configure(g_log_conf_file.c_str());
	pthread_mutex_init(&g_mutex, NULL);
	srand(time(NULL));
	NameSvrClient nsc;
	int ret = nsc.init("127.0.0.1", 3502, 100, 5, 4, 3, -1);
	if (ret < 0) { cout << "name svr client init error:" << ret << endl; return -1; }
	pthread_t t[THREAD_NUM];
	for (int i = 0; i < THREAD_NUM; i++) {
		pthread_create(&t[i], NULL, test_thread_routine, &nsc);
	}
	for (int i = 0; i < THREAD_NUM; i++) {
		pthread_join(t[i], NULL);
	}
	return 0;
}


int main(int argc, char * argv[]) {
	parse_args(argc, argv);
	return test();
}
